package sg.edu.nus.iss.team2s.jass.dao;

import java.util.Map;
import java.util.HashMap;

/**
 * DAOFactory is used to get the DAO implementation based on DTO class name and DAO type.
 * The DAO implementation configuration can be loaded from daoConfig.xml. The DAO element format is as the following:
 * <pre>
 * {@code <DAO dtoType="sg.edu.nus.iss.team2s.jass.dto.Advertiser" daoType="PROPERTIES" implementation="sg.edu.nus.iss.team2s.jass.dao.AdvertiserDAO" /> }
 * </pre>
 * 
 * @author Zheng Xiaofeng
 * @version 1.0 2009/09/21
 */
public class DAOFactory {
	/**
	 * Properties file DAO implementation type
	 */
	public static final String PROP_DAO = "PROPERTIES";
	/**
	 * JDBC DAO implementation type
	 */
	public static final String JDBC_DAO = "JDBC";
	/**
	 * Hibernate DAO implementation type
	 */
	public static final String HIBERNATE_DAO = "HIBERNATE";
	private Map<String, String> daoConfig = null;
	private static DAOFactory instance = null;
	
	private DAOFactory(){
		//load the dao configuration into daoConfig Map
		//the key should be dtoType|daoType, the value is the full class name
		loadDAOConfig();
	}
	
	private void loadDAOConfig(){
		/*
		 * load DAO implementation configuration from xml file, the DAO element is as the following:
		 * <DAO dtoType="sg.edu.nus.iss.team2s.jass.dto.Advertiser" daoType="PROPERTIES" implementation="sg.edu.nus.iss.team2s.jass.dao.AdvertiserDAO" />
		 * Initially, this method has the dao configuration hard-coded here, later it can be refactored to load dao configurations from daoConfig.xml
		 */
		
		daoConfig = new HashMap<String, String>();
		daoConfig.put("sg.edu.nus.iss.team2s.jass.dto.Advertiser|" + PROP_DAO, "sg.edu.nus.iss.team2s.jass.dao.AdvertiserDAO");
		daoConfig.put("sg.edu.nus.iss.team2s.jass.dto.JobSeeker|" + PROP_DAO, "sg.edu.nus.iss.team2s.jass.dao.JobSeekerDAO");
		daoConfig.put("sg.edu.nus.iss.team2s.jass.dto.Company|" + PROP_DAO, "sg.edu.nus.iss.team2s.jass.dao.CompanyDAO");
		daoConfig.put("sg.edu.nus.iss.team2s.jass.dto.JobAdvert|" + PROP_DAO, "sg.edu.nus.iss.team2s.jass.dao.JobAdvertDAO");
		daoConfig.put("sg.edu.nus.iss.team2s.jass.dto.JobAdvertResponse|" + PROP_DAO, "sg.edu.nus.iss.team2s.jass.dao.JobAdvertResponseDAO");
		daoConfig.put("sg.edu.nus.iss.team2s.jass.dto.User|" + PROP_DAO, "sg.edu.nus.iss.team2s.jass.dao.UserDAO");
	}
	/**
	 * get the singleton instance of DAOFactory
	 * @return DAOFactory
	 */
	public synchronized static DAOFactory getInstance(){
		if(instance == null){
			instance = new DAOFactory();
		}
		return instance;
	}
	/**
	 * get the default DAO implementation for dto class
	 * @param className dto class name
	 * @return DAOInterface Properties file DAO implementation, return null if no DAO implementation class is found
	 */
	public DAOInterface getDAO(String className){
		return getDAO(className, PROP_DAO);
	}
	/**
	 * get the DAO implementation for dto class based on the DAO type provided
	 * @param className dto class name
	 * @param daoType DAO type
	 * @return DAOInterface DAO implementation, return null if no DAO implementation class is found
	 */
	public DAOInterface getDAO(String className, String daoType){
		DAOInterface dao = null;
		String key = className + "|" + daoType;
		String impleClassName = (String)daoConfig.get(key);
//		System.out.println("key:" + key);
		if(impleClassName != null){
			try {
				dao = (DAOInterface)Class.forName(impleClassName).newInstance();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return dao;
	}
}
